#include "XMLExport.h" 

#include <list>

using namespace std;


void XMLExport::generateOutput(string outputName)
{
	//mParentModuleData->debug();
	string fileName = outputName.append(".xml");

	TiXmlDocument output;
	TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "UTF-8", "" );
	TiXmlElement* systemc = new TiXmlElement("SystemCModel");

	TiXmlElement* moduleList = new TiXmlElement( "ModuleList" );
	TiXmlElement* channelList = new TiXmlElement("ChannelList");
	output.LinkEndChild(decl);
	

	generateModuleDataOutput(moduleList, mParentModuleData);
	systemc->InsertEndChild(*moduleList);

	

	generateChannelDataOutput(channelList, mParentModuleData);
	systemc->InsertEndChild(*channelList);

	output.LinkEndChild(systemc);


	
	output.SaveFile( fileName.c_str() );
}

void XMLExport::generateModuleDataOutput(TiXmlElement* parentElement, ModuleData* moduleData)
{
	list <ModuleData*>* childModules = moduleData->getModuleDataList();
	list <ModuleData*>::const_iterator i;

	TiXmlElement* module = new TiXmlElement("Module");
	module->SetAttribute("name", moduleData->getName().c_str());

	for(i = childModules->begin() ; i != childModules->end();i++)
	{
		generateModuleDataOutput(module, (*i));
	}
	
	list<Process*>* processList = moduleData->getProcessList();
	for (list<Process*>::iterator j = processList->begin(); j != processList->end(); j++)
	{
		string processID;
		TiXmlElement* process = new TiXmlElement("Process");
		process->SetAttribute("name", (*j)->getName().c_str());
		process->SetAttribute("type", (*j)->getType().c_str());

		module->InsertEndChild(*process);
	}

	list<PortData*>* portDataList = moduleData->getPortDataList();
	for (list<PortData*>::iterator j = portDataList->begin(); j != portDataList->end(); j++)
	{
		string portDataID;
		TiXmlElement* portData = new TiXmlElement("Port");
		portData->SetAttribute("name", (*j)->getName().c_str());
		portData->SetAttribute("type", (*j)->getType().c_str());
		portData->SetAttribute("inout", (*j)->getInOut().c_str());

		module->InsertEndChild(*portData);
	}


	parentElement->InsertEndChild(*module);
	
}

void XMLExport::generateChannelDataOutput(TiXmlElement* parentElement, ModuleData* moduleData)
{
	list <ModuleData*>* childModules = moduleData->getModuleDataList();
	if (!childModules->empty())
	{
		for(list<ModuleData*>::iterator i = childModules->begin() ; i != childModules->end();i++)
		{
			generateChannelDataOutput(parentElement, (*i));
		}
	}

	list<ChannelData*>* channelDataList = moduleData->getChannelDataList();
	for (list<ChannelData*>::iterator j = channelDataList->begin(); j != channelDataList->end(); j++)
	{
		TiXmlElement* channel = new TiXmlElement("Channel");
		channel->SetAttribute("sourceModule", (*j)->getSourceModuleData()->getName().c_str());
		channel->SetAttribute("sourcePort", (*j)->getSourceName().c_str());

		channel->SetAttribute("targetModule", (*j)->getTargetModuleData()->getName().c_str());
		channel->SetAttribute("targetPort", (*j)->getTargetName().c_str());

		if ((*j)->isBidirectional()) channel->SetAttribute("bidirectional", "true");
		else channel->SetAttribute("bidirectional", "false");
		

		parentElement->InsertEndChild(*channel);
	}
	
}